#include <iostream>
#include <memory>
#include <string>

class Animal
{
public:
    virtual void Name() = 0;
};

class Fruit
{
public:
    virtual void Name() = 0;
};

class Factory
{
public:
    virtual std::shared_ptr<Fruit> CreateFruit(const std::string &name) = 0;
    virtual std::shared_ptr<Animal> CreateAnimal(const std::string &name) = 0;
};

class Apple : public Fruit
{
public:
    void Name()
    {
        printf("我是一个苹果\n");
    }
};

class Banana : public Fruit
{
public:
    void Name()
    {
        printf("我是一个香蕉\n");
    }
};

class Dog : public Animal
{
public:
    void Name()
    {
        printf("我是一只小狗\n");
    }
};

class Lamp : public Animal
{
public:
    void Name()
    {
        printf("我是一只山羊\n");
    }
};

class FruitFactory : public Factory
{
public:
    std::shared_ptr<Fruit> CreateFruit(const std::string &name) override
    {
        if (name == "苹果")
        {
            return std::make_shared<Apple>();
        }
        else if (name == "香蕉")
        {
            return std::make_shared<Banana>();
        }
        return nullptr;
    }
    std::shared_ptr<Animal> CreateAnimal(const std::string &name) override
    {
        return nullptr;
    }
};

class AnimalFactory : public Factory
{
public:
    std::shared_ptr<Animal> CreateAnimal(const std::string &name) override
    {
        if (name == "小狗")
        {
            return std::make_shared<Dog>();
        }
        else if (name == "山羊")
        {
            return std::make_shared<Lamp>();
        }
        return nullptr;
    }
    std::shared_ptr<Fruit> CreateFruit(const std::string &name) override
    {
        return nullptr;
    }
};

class FactoryProducer
{
public:
    static std::shared_ptr<Factory> CreateFactory(const std::string &name)
    {
        if (name == "水果")
        {
            return std::make_shared<FruitFactory>();
        }
        else if (name == "动物")
        {
            return std::make_shared<AnimalFactory>();
        }
        return nullptr;
    }
};

int main()
{
    std::shared_ptr<Factory> animal_factory = FactoryProducer::CreateFactory("动物");
    std::shared_ptr<Animal> animal = animal_factory->CreateAnimal("小狗");
    animal->Name();
    animal = animal_factory->CreateAnimal("山羊");
    animal->Name();
    std::shared_ptr<Factory> fruit_factory = FactoryProducer::CreateFactory("水果");
    std::shared_ptr<Fruit> fruit = fruit_factory->CreateFruit("苹果");
    fruit->Name();
    fruit = fruit_factory->CreateFruit("香蕉");
    fruit->Name();
    return 0;
}